#include "BlockQueue.hpp"
#include "Thread.hpp"
#include <iostream>
#include <vector>
#include <unistd.h>
using namespace ThreadModule;
#include "Task.hpp"
using blockqueue_t = BlockQueue<Task>;



void Productor(blockqueue_t& bq)
{
    // int i = 0;
    // //产生数据
    // while(true)
    // {
    //     //生产慢一点，生产一条数据，消费一条数据
    //     //sleep(1);
    //     //生产数据
    //     bq.Enqueue(i);
    //     std::cout << "Productor product data :" << i++ << std::endl;
    // }
    while(true)
    {
        sleep(1);
        bq.Enqueue(DownLoad);
    }
}

void Consumer(blockqueue_t& bq)
{
    // while(true)
    // {
    //     //消费慢一点，消费一条数据，生产一条数据
    //     //sleep(1);
    //     //获取并消费数据
    //     int data = 0;
    //     bq.Pop(&data);
    //     std::cout << "Consumer consum data : " << data << std::endl;
    // }
    while(true)
    {
        //获取数据
        Task t;
        bq.Pop(&t);
        //消费数据
        t();
    }
}

void InitComm(std::vector<Thread<blockqueue_t>>& threads, int num, func_t<blockqueue_t> func, blockqueue_t& bq, const std::string& name)
{
    for (int i = 0; i < num; i++)
    {
        std::string thraedName = name + std::to_string(i + 1);
        threads.emplace_back(func, bq, thraedName);
    }
}

void InitProductor(std::vector<Thread<blockqueue_t>>& threads, int num, blockqueue_t& bq)
{
    InitComm(threads, num, Productor, bq, "productor");
}

void InitConsumer(std::vector<Thread<blockqueue_t>>& threads, int num, blockqueue_t& bq)
{
    InitComm(threads, num, Consumer, bq, "consumer");
}

void StartAllThread(std::vector<Thread<blockqueue_t>>& threads)
{
    for (auto& thread : threads)
        thread.Start();
}

void WaitAllThread(std::vector<Thread<blockqueue_t>>& threads)
{
    for (auto& thread : threads)
        thread.Join();
}

int main()
{
    blockqueue_t* bq = new blockqueue_t(5);
    std::vector<Thread<blockqueue_t>> threads;
    InitProductor(threads, 1, *bq);
    InitConsumer(threads, 1, *bq);
    StartAllThread(threads);
    WaitAllThread(threads);
    return 0;
}